home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
FINGCLI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-01-11
|
6KB
|
267 lines
/*
*
* Finger support...
*
* Finger client routines. Written by Michael T. Horne - KA7AXD.
* Copyright 1988 by Michael T. Horne, All Rights Reserved.
* Permission granted for non-commercial use and copying, provided
* that this notice is retained.
*
*/
#include <stdio.h>
#ifdef MSC
#include <sys/types.h>
#endif
#include "global.h"
#include "mbuf.h"
#include "timer.h"
#include "internet.h"
#include "icmp.h"
#include "netuser.h"
#include "tcp.h"
#include "finger.h"
#include "session.h"
extern char badhost[],
hostname[];
/*
*
* Open up a socket to a remote (or the local) host on its finger port.
*
*/
int
dofinger(argc,argv)
int argc;
char *argv[];
{
void f_state(),
fingcli_rcv();
struct session *s;
struct tcb *tcb;
struct socket lsocket,
fsocket;
struct finger *finger, *alloc_finger();
char *host;
lsocket.address = ip_addr;
lsocket.port = lport++;
/*
* Extract user/host information. It can be of the form:
*
* finger user, # finger local user
* finger user@host, # finger remote user
* finger @host # finger host (give system status)
*
*/
if ((finger = alloc_finger()) == NULLFING)
return(1);
if ((host = index(argv[1], '@')) == NULLCHAR) {
fsocket.address = ip_addr; /* no host, use local */
if ((finger->user = malloc(strlen(argv[1]) + 3)) == NULLCHAR) {
free_finger(finger);
return(1);
}
strcpy(finger->user, argv[1]);
strcat(finger->user, "\015\012");
}
else {
*host++ = '\0'; /* null terminate user name */
if (*host == '\0') { /* must specify host */
printf("%s: no host specified\n", argv[0]);
free_finger(finger);
return(-1);
}
if ((fsocket.address = resolve(host)) == 0) {
printf("%s: ", argv[0]);
printf(badhost, host);
free_finger(finger);
return(1);
}
if ((finger->user = malloc(strlen(argv[1])+3))==NULLCHAR) {
free_finger(finger);
return 1;
}
strcpy(finger->user, argv[1]);
strcat(finger->user, "\015\012");
}
fsocket.port = FINGER_PORT; /* use finger wnp */
/* Allocate a session descriptor */
if ((s = newsession()) == NULLSESSION){
printf("Too many sessions\n");
free_finger(finger);
return 1;
}
current = s;
s->cb.finger = finger;
finger->session = s;
if (host == NULLCHAR) /* if no host specified */
host = hostname; /* use local host name */
if ((s->name = malloc(strlen(host)+1)) != NULLCHAR)
strcpy(s->name, host);
s->type = FINGER;
s->parse = (int (*)()) NULL;
tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
fingcli_rcv, (void (*)()) 0, f_state, 0, (int *) finger);
finger->tcb = tcb;
tcb->user = (char *)finger; /* cast into what belonges there */
go();
return 0;
}
/*
* Allocate a finger structure for the new session
*/
struct finger *
alloc_finger()
{
struct finger *tmp;
if ((tmp = (struct finger *) malloc(sizeof(struct finger))) == NULLFING)
return(NULLFING);
tmp->session = NULLSESSION;
tmp->user = (char *) NULL;
return(tmp);
}
/*
* Free a finger structure
*/
int
free_finger(finger)
struct finger *finger;
{
if (finger != NULLFING) {
if (finger->session != NULLSESSION)
freesession(finger->session);
if (finger->user != (char *) NULL)
free(finger->user);
free(finger);
}
return 0;
}
/* Finger receiver upcall routine */
void
fingcli_rcv(tcb, cnt)
register struct tcb *tcb;
int16 cnt;
{
struct mbuf *bp;
char *buf;
/* Make sure valid finger session */
if ((struct finger *) tcb->user == NULLFING) {
return;
}
/* Hold output if we're not the current session */
if (mode != CONV_MODE || current == NULLSESSION
|| current->type != FINGER
|| current->cb.finger != (struct finger *)tcb->user)
return;
if (recv_tcp(tcb, &bp, cnt) > 0)
while (bp != NULLBUF) {
buf = bp->data;
while(bp->cnt--) {
switch (*buf) {
case '\012':
break;
case '\015':
fputs("\n", stdout);
break;
#ifdef MSDOS
case '\032': /* CPMEOF (dont hang doubledos!) */
break;
#endif
default:
fputc(*buf, stdout);
break;
}
if(current->record != NULLFILE)
fputc(*buf,current->record);
buf++;
}
bp = free_mbuf(bp);
}
fflush(stdout);
}
/* State change upcall routine */
void
f_state(tcb,old,new)
register struct tcb *tcb;
char old, /* old state */
new; /* new state */
{
struct finger *finger;
char notify = 0;
extern char *tcpstates[];
extern char *reasons[];
extern char *unreach[];
extern char *exceed[];
struct mbuf *bp;
finger = (struct finger *)tcb->user;
if(current != NULLSESSION && current->type == FINGER)
notify = 1;
switch(new){
case CLOSE_WAIT:
if(notify)
printf("%s\n",tcpstates[new]);
close_tcp(tcb);
break;
case CLOSED: /* finish up */
if(notify) {
printf("%s (%s", tcpstates[new], reasons[tcb->reason]);
if (tcb->reason == NETWORK){
switch(tcb->type){
case DEST_UNREACH:
printf(": %s unreachable",unreach[tcb->code]);
break;
case TIME_EXCEED:
printf(": %s time exceeded",exceed[tcb->code]);
break;
}
}
printf(")\n");
cmdmode();
}
if(finger != NULLFING)
free_finger(finger);
del_tcp(tcb);
break;
case ESTABLISHED:
if (notify) {
printf("%s\n",tcpstates[new]);
printf("[%s]\n", current->name);
}
bp = qdata(finger->user, (int16) strlen(finger->user));
send_tcp(tcb, bp);
break;
default:
if(notify)
printf("%s\n",tcpstates[new]);
break;
}
fflush(stdout);
}